package com.csz.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

/** @author zanona */
public abstract class Persistencia {

    //private static final String URL = "jdbc:mysql://leoserver.dyndns.tv:3306/turismorbc";
    private static final String URL = "jdbc:mysql://localhost:3306/turismorbc";
    private static final String USERNAME = "arthur";
    private static final String PASSWORD = "ze";
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static Connection conexao = null;
    
    protected  Integer id ;

    public abstract void salvar();

    public static Object consultar(Integer id) {
        return null;
    };

    public static List<Object> consultar() {
        return null;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public static List<Object> consultarNamedQuery(String namedQuery, List<Object> params) {
        return null;
    }

    public static List<Object[]> consultarNamedQueryGenerica (String namedQuery, List<Object> params) {
         List<Object[]> rowset = new ArrayList<Object[]>();
         PreparedStatement ps = createStatementNamedQuery( namedQuery, params );
        try {
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData rsm = rs.getMetaData();
            // para todas as linhas
            while ( rs.next() ) {
                Object[] lista = new Object[rsm.getColumnCount()];
                // para todas as colunas
                for ( int i = 0 ; i < lista.length ; i++ ) {
                    lista[i] = rs.getObject(i+1);
                }
                // salve as tuplas como um registro
                rowset.add(lista);
            }
        } catch (SQLException ex) {}
        return rowset;
    }

    public abstract void remover();

    //executa uma namedQuery, seta os parametros dela e retorna um id
    // o ultimo parametro sempre é o de saida do banco de dados
    
    protected static Object callNamedStoredProcedure(String namedQuery, List<Object> params , Class tipoRetorno ) {
        Connection c = getConexao();
        try {
            CallableStatement cs = c.prepareCall(namedQuery);
            // se pediu retorno, entao, eu adiociono todos os parametros do array como IN, senao deixo o ultimo como out
            int numParams = tipoRetorno == null ? params.size() : params.size() - 1;
            for (int i = 0; i < numParams ; i++) {
                Object o = params.get(i);
                cs.setObject(i+1, o);
            }
            // se passou o tipo de retorno, tem que adiocionar nos params do sql
            if ( tipoRetorno != null ) {
                // definindo o retorno
                int tipoRetornoJava = 0;
                if ( tipoRetorno == String.class ) tipoRetornoJava = Types.VARCHAR;
                else if ( tipoRetorno == Integer.class ) tipoRetornoJava = Types.INTEGER;
                else if ( tipoRetorno == Character.class ) tipoRetornoJava = Types.CHAR;
                // fim definicao retorno
                cs.registerOutParameter(params.size() , tipoRetornoJava );
            }
            cs.execute();
            return cs.getObject(params.size());
        } catch (SQLException ex) {

        }
        return null;
    }

    // recebe uma namedQuery, seta os parametros dela e retorna o resultset
    public static PreparedStatement createStatementNamedQuery(String namedQuery, List<Object> params) {
        Connection c = getConexao();
        try {
            PreparedStatement ps = c.prepareStatement(namedQuery);
            for (int i = 0; i < params.size(); i++) {
                Object o = params.get(i);
                ps.setObject(i + 1, o);
            }
            return ps;
        } catch (SQLException ex) {}
        return null;
    }

    public static Connection getConexao() {
        if ( conexao != null ) return conexao;
        try {
            Class.forName(DRIVER);
            conexao = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (ClassNotFoundException e) {
        } catch (SQLException e) {
        }
        return conexao;
    }
}
